package cn.slimsmart.thrift.rpc.demo.server;

import java.util.concurrent.Executors;

import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.TProcessor;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TServerSocket;

import cn.slimsmart.thrift.rpc.demo.service.EchoSerivce;
import cn.slimsmart.thrift.rpc.demo.service.EchoSerivceImpl;
import cn.slimsmart.thrift.rpc.demo.service.HelloWorldService;
import cn.slimsmart.thrift.rpc.demo.service.HelloWorldServiceImpl;

/**
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class MulitServerDemo {
	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld TSimpleServer start ....");
			final TMultiplexedProcessor processor = new TMultiplexedProcessor();
			final TProcessor tprocessor1 = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());
			final TProcessor tprocessor2 = new EchoSerivce.Processor<EchoSerivce.Iface>(new EchoSerivceImpl());
		    processor.registerProcessor("HelloWorldService", tprocessor1);
		    processor.registerProcessor("EchoSerivce", tprocessor2);
			Executors.newSingleThreadExecutor().execute(new Runnable() {
				@Override
				public void run() {
					buildSimpleServer(processor,10000).serve();
				}
			});
		
			Executors.newSingleThreadExecutor().execute(new Runnable() {
				@Override
				public void run() {
					buildNoBlockServer(processor,10001).serve();
				}
			});
			
			Executors.newSingleThreadExecutor().execute(new Runnable() {
				@Override
				public void run() {
					buildHsHaServer(processor,10002).serve();
				}
			});
			
			Executors.newSingleThreadExecutor().execute(new Runnable() {
				@Override
				public void run() {
					buildThreadPoolServer(processor,10003).serve();
				}
			});
			
			Executors.newSingleThreadExecutor().execute(new Runnable() {
				@Override
				public void run() {
					buildTThreadedSelectorServer(processor,10004).serve();
				}
			});
						
			System.out.println("HelloWorld TSimpleServer start end....");
			
		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}

	private TServer buildSimpleServer(TProcessor tprocessor,Integer port){
		TServer server=null;
		try {
			// 简单的单线程服务模型，一般用于测试
			TServerSocket serverTransport = new TServerSocket(port);
			TServer.Args tArgs = new TServer.Args(serverTransport);
			tArgs.transportFactory(new TFramedTransport.Factory());  
			tArgs.processor(tprocessor);
			tArgs.protocolFactory(new TCompactProtocol.Factory());
			server = new TSimpleServer(tArgs);
			server.serve();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return server;
	}
	
	
	private TServer buildNoBlockServer(TProcessor tprocessor,Integer port){
		TServer server=null;
		try {
			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port);
			TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
			tnbArgs.processor(tprocessor);
			tnbArgs.protocolFactory(new TCompactProtocol.Factory());
			tnbArgs.transportFactory(new TFramedTransport.Factory());
			server = new TNonblockingServer(tnbArgs);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return server;
	}
	
	
	private TServer buildHsHaServer(TProcessor tprocessor,Integer port){
		TServer server=null;
		try {
			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port);
			THsHaServer.Args thhsArgs = new THsHaServer.Args(tnbSocketTransport);
			thhsArgs.processor(tprocessor);
			thhsArgs.transportFactory(new TFramedTransport.Factory());
			thhsArgs.protocolFactory(new TCompactProtocol.Factory());
			//半同步半异步的服务模型
			server = new THsHaServer(thhsArgs);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return server;
	}
	
	private TServer buildThreadPoolServer(TProcessor tprocessor,Integer port){
		TServer server=null;
		try {
			TServerSocket serverTransport = new TServerSocket(port);
			TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(serverTransport);
			ttpsArgs.processor(tprocessor);
			ttpsArgs.protocolFactory(new TCompactProtocol.Factory());
			ttpsArgs.transportFactory(new TFramedTransport.Factory());
			server = new TThreadPoolServer(ttpsArgs);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return server;
	}
	
	
	private TServer buildTThreadedSelectorServer(TProcessor tprocessor,Integer port){
		TServer server=null;
		try {
			TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(port);
			TThreadedSelectorServer.Args tArgs = new TThreadedSelectorServer.Args(serverTransport);  
			tArgs.processor(tprocessor);
			tArgs.protocolFactory( new TCompactProtocol.Factory()); 
			tArgs.transportFactory(new TFramedTransport.Factory());  
			server=new TThreadedSelectorServer(tArgs); 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return server;
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MulitServerDemo server = new MulitServerDemo();
		server.startServer();
	}

}